home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / REALITY / atom / panel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  24.0 KB  |  980 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /* panel.c
  18.  * -------
  19.  *
  20.  * $Revision: 1.23 $
  21.  *
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <fmclient.h>
  26. #include <gl/gl.h>
  27. #include <gl/device.h>
  28. #include <gl/sphere.h>
  29.  
  30. #include "panel.h"
  31. #include "mview.h"
  32. #include "geom.h"
  33.  
  34. #define COLOR_RAMP_SIZE 8
  35.  
  36. extern fmfonthandle FontScreen, FontScreen5, FontScreen8;
  37. extern fmfontinfo FontScreenInfo, FontScreen5Info, FontScreen8Info;
  38.  
  39. long PanelWid = -1;
  40. int PanelButtonDown = 0;
  41.  
  42. static float RangeRadScaleFactor;
  43.  
  44. static unsigned long WhiteRamp[COLOR_RAMP_SIZE];
  45. static unsigned long RedRamp[COLOR_RAMP_SIZE];
  46.  
  47. static long PanelXorigin, PanelYorigin;
  48. static int PanelPrefposition = 0;
  49.  
  50. static float Value(float m1, float m2, float hue);
  51. static unsigned long HLStoRGB(float h, float l, float s);
  52. static void DrawBack(ITEM *item);
  53. static void DrawText(char text[], ITEM *item);
  54. static void BevelRect(RECT *rect, int pushed, unsigned long *c, int width);
  55. static void DrawName(char *name, RECT *rect);
  56.  
  57. static void DspEvent(ITEM *item);
  58. static void SelectQuit(ITEM *item, long dev);
  59. static void SelectHelp(ITEM *item, long dev);
  60. static void SelectReset(ITEM *item, long dev);
  61. static void DspSphereType(ITEM *item);
  62. static void SelectSphereType(ITEM *item, long dev);
  63. static void DspSpherePrim(ITEM *item);
  64. static void SelectSpherePrim(ITEM *item, long dev);
  65. static void DspSphereDepth(ITEM *item);
  66. static void SelectSphereDepth(ITEM *item, long dev);
  67. static void DspAtomAccBuf(ITEM *item);
  68. static void SelectAtomAccBuf(ITEM *item, long dev);
  69. static void DspBondAccBuf(ITEM *item);
  70. static void SelectBondAccBuf(ITEM *item, long dev);
  71. static void DspBondSmooth(ITEM *item);
  72. static void SelectBondSmooth(ITEM *item, long dev);
  73. static void DspBondEndCorrect(ITEM *item);
  74. static void SelectBondEndCorrect(ITEM *item, long dev);
  75. static void DspRadius(ITEM *item);
  76. static void SelectRadius(ITEM *item, long dev);
  77. static void DspModel(ITEM *item);
  78. static void SelectModel(ITEM *item, long dev);
  79. static void SelectMultisample(ITEM *item, long dev);
  80. static void SelectStereo(ITEM *item, long dev);
  81. static void SelectPerspective(ITEM *item, long dev);
  82. static void DspProjection(ITEM *item);
  83. static void SelectBitmapSpheres(ITEM *item, long dev);
  84.  
  85. static void DspOnOff(ITEM *item);
  86. static void SelectOnOff(ITEM *item, long dev);
  87.  
  88. ITEM *PrevItem = 0;
  89. ITEM Items[NUM_ITEMS] = {
  90.     {"Quit",            {  10, 110,  10,  40}, DspEvent, SelectQuit, 
  91.     NULL, NULL, STATUS_DEFAULT, WhiteRamp}, 
  92.     {"Help",            {  10, 110,  60,  90}, DspEvent, SelectHelp, 
  93.     NULL, NULL,  STATUS_DEFAULT, WhiteRamp}, 
  94.     {"Reset",            {  10, 110, 110, 140}, DspEvent, SelectReset, 
  95.     NULL, NULL, STATUS_DEFAULT, WhiteRamp}, 
  96.     {"Models",            {  10, 110, 160, 190}, DspModel, SelectModel, 
  97.     NULL, &ModelId, STATUS_DEFAULT, WhiteRamp}, 
  98.     {"Display Atoms",        { 120, 230,  10,  35}, DspOnOff, 
  99.     SelectOnOff, DoDispAtoms, &DispAtoms, STATUS_DEFAULT, WhiteRamp}, 
  100.     {"Display Bonds",        { 120, 230,  60,  85}, DspOnOff, 
  101.     SelectOnOff, DoDispBonds, &DispBonds, STATUS_DEFAULT, WhiteRamp}, 
  102.     {"Bitmap Spheres",        { 120, 230, 110, 135}, DspOnOff, 
  103.     SelectBitmapSpheres, DoBitmapSpheres, &BitmapSpheres, 
  104.     STATUS_DEFAULT, WhiteRamp}, 
  105.     {"Sphere Type",        { 240, 350,  10,  35}, DspSphereType, 
  106.     SelectSphereType, NULL, &SphereType, STATUS_DEFAULT, WhiteRamp}, 
  107.     {"Sphere Primitive",    { 240, 350,  60,  85}, DspSpherePrim, 
  108.     SelectSpherePrim, NULL, &SpherePrim, STATUS_DEFAULT, WhiteRamp}, 
  109.     {"Sphere Depth",        { 240, 350, 110, 135}, DspSphereDepth, 
  110.     SelectSphereDepth, NULL, &SphereDepth, STATUS_DEFAULT, WhiteRamp},
  111.     {"Hemi Spheres",        { 360, 470,  10,  35}, DspOnOff, SelectOnOff, 
  112.     DoHemi, &Hemi, STATUS_DEFAULT, WhiteRamp},
  113.     {"Sph Orient",          { 360, 470,  60,  85}, DspOnOff, SelectOnOff, 
  114.     DoOrient, &Orient, STATUS_DEFAULT, WhiteRamp},
  115.     {"Accumulate Atoms",    { 480, 590,  10,  35}, DspOnOff, 
  116.     SelectAtomAccBuf, InitAccBuf, &AtomAccBuf, STATUS_DEFAULT, WhiteRamp}, 
  117.     {"SpinMode",        { 480, 590,  60,  85}, DspOnOff, 
  118.     SelectOnOff, DoSpinMode, &SpinMode, STATUS_DEFAULT, WhiteRamp},
  119.     {"RollMode",        { 480, 590, 110, 135}, DspOnOff, 
  120.     SelectOnOff, DoAccRollMode, &RollMode, STATUS_DEFAULT, WhiteRamp},
  121.     {"Accumulate Bonds",    { 600, 710,  10,  35}, DspOnOff, 
  122.     SelectBondAccBuf, InitAccBuf, &BondAccBuf, STATUS_DEFAULT, WhiteRamp}, 
  123.     {"Smooth Bonds",        { 600, 710,  60,  85}, DspBondSmooth, 
  124.     SelectBondSmooth, NULL, &BondSmooth, STATUS_DEFAULT, WhiteRamp}, 
  125.     {"End Correct Bonds",   { 600, 710, 110, 135}, DspBondEndCorrect,
  126.     SelectBondEndCorrect, NULL, &BondSmooth, STATUS_DEFAULT, WhiteRamp}, 
  127.     {"Multisample",        { 480, 590, 160, 185}, DspOnOff,
  128.     SelectMultisample, DoMultisample, &Multisample, STATUS_DEFAULT, WhiteRamp}, 
  129.     {"Stereo",            { 600, 710, 160, 185}, DspOnOff,
  130.     SelectStereo, DoStereo, &Stereo, STATUS_DEFAULT, WhiteRamp}, 
  131.     {"Projection",        { 360, 470,  110,  135}, DspProjection,
  132.     SelectPerspective, DoProjection, &Perspective, STATUS_DEFAULT, WhiteRamp}, 
  133.     {"Depthcue",        { 360, 470,  160,  185}, DspOnOff,
  134.     SelectOnOff, NULL, &Depthcue, STATUS_DEFAULT, WhiteRamp}, 
  135. };
  136.  
  137. ITEM *orientItem =  &Items[11];
  138. ITEM *msItem =  &Items[18];
  139. ITEM *accAtomItem =  &Items[12];
  140. ITEM *accBondItem =  &Items[15];
  141. ITEM *stereoItem =  &Items[19];
  142. ITEM *projItem =  &Items[20];
  143.  
  144. ITEM RadiusItem = {
  145.     "Radius",            { 120, 350, 160, 200}, DspRadius, SelectRadius, 
  146.                     ChangeRadius, (int *)&RadScaleFactor, 
  147. };
  148.  
  149. /* Initialization stuff */
  150.  
  151. void InitPanel()
  152. {
  153.     int i;
  154.  
  155.     for (i = 1; i <= COLOR_RAMP_SIZE; i++) {
  156.     WhiteRamp[i-1] = HLStoRGB(0.0, (float) i / 8.0, 0.0);
  157.     RedRamp[i-1] = HLStoRGB(0.0, (float) i / 8.0, 0.3);
  158.     }
  159. }
  160.  
  161. static float Value(float m1, float m2, float hue)
  162. {
  163.     if (hue > 360.0) hue -= 360.0;
  164.     else if (hue < 0.0) hue += 360.0;
  165.  
  166.     if (hue < 60.0) return (m1 + (m2 - m1) * hue / 60.0);
  167.     else if (hue < 180.0) return m2;
  168.     else if (hue < 240.0) return (m1 + (m2 - m1) * (240.0 - hue) / 60.0);
  169.     else return m1;
  170. }
  171.  
  172. static unsigned long HLStoRGB(float h, float l, float s)
  173. {
  174.     float r, g, b;
  175.     float m1, m2;
  176.  
  177.     if (l < 0.5) m2 = l * (1 + s);
  178.     else m2 = l + s - l * s;
  179.     m1 = 2 * l - m2;
  180.     if (s = 0.0) r = g = b = l;
  181.     else {
  182.     r = Value(m1, m2, h + 120);
  183.     g = Value(m1, m2, h);
  184.     b = Value(m1, m2, h - 120);
  185.     }
  186.     return ((((char) (b * 255.0)) << 16) | (((char) (g * 255.0)) << 8) |
  187.     ((char) (r * 255.0)));
  188. }
  189.  
  190. /* Window Stuff */
  191.  
  192. void OpenPanelWindow()
  193. {
  194.     if (PanelPrefposition)
  195.     prefposition(PanelXorigin, PanelXorigin + PANEL_WIDTH, 
  196.         PanelYorigin, PanelYorigin + PANEL_HEIGHT);
  197.     else prefsize(PANEL_WIDTH, PANEL_HEIGHT);
  198.     PanelWid = winopen("panel");
  199.     RGBmode();
  200.     if (PanelWid == -1) {
  201.     fprintf(stderr, "no additional graphics windows are available\n");
  202.     DoExit(-1);
  203.     }
  204. #ifdef DEBUG
  205.     if (!Debug)
  206.     doublebuffer();
  207. #else
  208.     doublebuffer();
  209. #endif
  210.     gconfig();
  211.     getorigin(&PanelXorigin, &PanelYorigin);
  212.     PanelPrefposition = 1;
  213.     cpack(WhiteRamp[6]);
  214.     clear();
  215. #ifdef DEBUG
  216.     if (!Debug) {
  217.     swapbuffers();
  218.     clear();
  219.     }
  220. #endif
  221.     swapbuffers();
  222.     clear();
  223.     RangeRadScaleFactor = MaxRadScaleFactor - MinRadScaleFactor;
  224. }
  225.  
  226.  
  227. static void DspOnOff(ITEM *item)
  228. {
  229.     DrawBack(item);    
  230.     if (*(item->val)) DrawText("On", item);
  231.     else DrawText("Off", item);
  232.     DrawName(item->name, &(item->rect));
  233. }
  234.  
  235. static void SelectOnOff(ITEM *item, long dev)
  236. {
  237.     *(item->val) = 1 - *(item->val);
  238.     if (item->action)
  239.     item->action();
  240.     DisplayScene();
  241.     winset(PanelWid);
  242.     item->status = SET_PUSHED(0, item->status);
  243.     frontbuffer(1);
  244.     item->dsp(item);
  245.     frontbuffer(0);
  246. }
  247.  
  248.  
  249. void ClosePanelWindow()
  250. {
  251.     winclose(PanelWid);
  252.     PanelWid = -1;
  253. }
  254.  
  255. void DrawPanel()
  256. {
  257.     ITEM *item;
  258.  
  259.     winset(PanelWid);
  260. #ifdef DEBUG
  261.     if (Debug) {
  262.     cpack(WhiteRamp[6]);
  263.     clear();
  264.     }
  265. #endif
  266.     for (item = Items; item < &Items[NUM_ITEMS]; item++) {
  267.     item->dsp (item);
  268.     }
  269.     DspRadius(&RadiusItem);
  270. #ifdef DEBUG
  271.     if (!Debug) {
  272.     swapbuffers();
  273.     cpack(WhiteRamp[6]);
  274.     clear();
  275.     }
  276. #else
  277.     swapbuffers();
  278.     cpack(WhiteRamp[6]);
  279.     clear();
  280. #endif
  281. }
  282.  
  283. void DoEventsPanel(long dev, short val)
  284. {
  285.     ITEM *item;
  286.  
  287.     winset(PanelWid);
  288.     switch(dev) {
  289.  
  290.       case LEFTMOUSE:
  291.       case MIDDLEMOUSE:
  292.     if (val) {
  293.         PanelButtonDown = 1;
  294.         if (inrect(getvaluator(MOUSEX) - PanelXorigin,
  295.         getvaluator(MOUSEY) - PanelYorigin, RadiusItem.rect)) {
  296.         SelectRadius(&RadiusItem, dev);
  297.         return;
  298.         }
  299.     } else {
  300.         PanelButtonDown = 0;
  301.         PrevItem = 0;
  302.         for (item = Items; item < &Items[NUM_ITEMS]; item++) {
  303.         if (inrect(getvaluator(MOUSEX) - PanelXorigin,
  304.         getvaluator(MOUSEY) - PanelYorigin, item->rect)) {
  305.             item->select (item, dev);
  306.             return;
  307.         }
  308.         }
  309.     }
  310.     return;
  311.  
  312.       case RIGHTMOUSE:
  313.     return;
  314.  
  315.       case REDRAW:
  316.     reshapeviewport();
  317.     getorigin(&PanelXorigin, &PanelYorigin);
  318.     cpack(WhiteRamp[6]);
  319.     clear();
  320.     DrawPanel();
  321.     return;
  322.  
  323.       default:
  324.     return;
  325.     }
  326. }
  327.  
  328. void DoPanel(long dev, short val)
  329. {
  330.     ITEM *item;
  331.     long xpos, ypos;
  332.  
  333.     if (!PanelButtonDown) return;
  334.     winset(PanelWid);
  335.  
  336.     xpos = getvaluator(MOUSEX) - PanelXorigin;
  337.     ypos = getvaluator(MOUSEY) - PanelYorigin;
  338.  
  339.     if (PrevItem) {
  340.     if (inrect(xpos, ypos, PrevItem->rect))
  341.         return;
  342.     PrevItem->status = (GET_PUSHED(PrevItem->status)) ?
  343.         SET_PUSHED(0, PrevItem->status) : SET_PUSHED(1, PrevItem->status);
  344.     frontbuffer(1);
  345.     PrevItem->dsp(PrevItem);
  346.     frontbuffer(0);
  347.     PrevItem = 0;
  348.     }
  349.     for (item = Items; item < &Items[NUM_ITEMS]; item++) {
  350.     if (inrect(xpos, ypos, item->rect)) {
  351.         item->status = (GET_PUSHED(item->status)) ?
  352.         SET_PUSHED(0, item->status) : SET_PUSHED(1, item->status);
  353.         frontbuffer(1);
  354.         item->dsp(item);
  355.         frontbuffer(0);
  356.         PrevItem = item;
  357.         break;
  358.     }
  359.     }
  360. }
  361.  
  362. static void BevelRect(RECT *rect, int pushed, unsigned long *c, int width)
  363. {
  364.     int i;
  365.       
  366.     linewidth(1);
  367.     for(i = 0; i < width; i++) {
  368.     if (pushed) cpack(c[i]);
  369.     else cpack(c[7-i]);
  370.         move2i(rect->left + i, rect->bottom + i);
  371.         draw2i(rect->left + i, rect->top - i);
  372.         draw2i(rect->right - i, rect->top - i);
  373.     if (pushed) cpack(c[7-i]);
  374.     else cpack(c[i]);
  375.         move2i(rect->right - i, rect->top - i);
  376.         draw2i(rect->right - i, rect->bottom + i);
  377.         draw2i(rect->left + i, rect->bottom + i);
  378.     }   
  379. }           
  380.  
  381. static void DrawBack(ITEM *item)
  382. {
  383.     unsigned long status = item->status;
  384.     unsigned long *color_ramp = item->color_ramp;
  385.     int frame_width;
  386.  
  387.     cpack((GET_PUSHED(status)) ? 
  388.     ((GET_HIGHLITED(status)) ? color_ramp[4] : color_ramp[3]) : 
  389.     ((GET_HIGHLITED(status)) ? color_ramp[4] : color_ramp[3]));
  390.  
  391.     rectfi(item->rect.left, item->rect.bottom, 
  392.     item->rect.right, item->rect.top);
  393.  
  394.     if (GET_PUSHED(status)) BevelRect(&item->rect, 1, color_ramp, 4);
  395.     else BevelRect(&item->rect, 0, color_ramp, 4);
  396. }
  397.  
  398. static void DrawText(char text[], ITEM *item)
  399. {
  400.     unsigned long status = item->status;
  401.     unsigned long *color_ramp = item->color_ramp;
  402.     long x, y;
  403.  
  404.     if (GET_PUSHED(status)) cpack(color_ramp[7]);
  405.     else cpack(color_ramp[0]);
  406.     x = (item->rect.right - item->rect.left - fmgetstrwidth(FontScreen8, 
  407.     text)) / 2 + item->rect.left;
  408.     y = (item->rect.top - item->rect.bottom - FontScreen8Info.height) / 2 + 
  409.     item->rect.bottom;
  410.     fmsetfont(FontScreen8);
  411.     cmov2i(x, y);
  412.     fmprstr(text);
  413. }
  414.  
  415. static void DrawName(name, rect)
  416.     char name[];
  417.     RECT *rect;
  418. {
  419.     long x, y;
  420.  
  421.     cpack(0x0);
  422.     x = (rect->right - rect->left - fmgetstrwidth(FontScreen8, name)) / 2 + 
  423.     rect->left;
  424.     y = rect->top + FontScreen8Info.height / 2;
  425.     fmsetfont(FontScreen8);
  426.     cmov2i(x, y);
  427.     fmprstr(name);
  428. }
  429.  
  430. static void DspEvent(ITEM *item)
  431. {
  432.     DrawBack(item);
  433.     DrawText(item->name, item);
  434. }
  435.  
  436. static void DspSphereType(ITEM *item)
  437. {
  438.     DrawBack(item);    
  439.     switch (SphereType) {
  440.       case SPH_OCT: DrawText("oct", item); break;
  441.       case SPH_ICOS: DrawText("icos", item); break;
  442.       case SPH_CUBE: DrawText("cube", item); break;
  443.       case SPH_BARY: DrawText("bary", item); break;
  444.       case SPH_BILIN: DrawText("bilin", item); break;
  445.       default: break;
  446.     }
  447.     DrawName(item->name, &(item->rect));
  448. }
  449.  
  450. static void SelectSphereType(ITEM *item, long dev)
  451. {
  452.     if (dev == MIDDLEMOUSE) {
  453.     SphereType++;
  454.     SphereType %= NUMTESSTYPES;
  455.     } else {
  456.     if (SphereType == 0) SphereType = NUMTESSTYPES - 1;
  457.     else SphereType--;
  458.     }
  459.     sphmode(SPH_TESS, SphereType);
  460.     sphmode(SPH_TESS, SphereType);
  461.     CalcInfo();
  462.  
  463.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  464.     !Alreadyaccumulated)
  465.     DisplayAccScene();
  466.     else 
  467.     DisplayScene();
  468.  
  469.     winset(PanelWid);
  470.     item->status = SET_PUSHED(0, item->status);
  471.     frontbuffer(1);
  472.     item->dsp(item);
  473.     frontbuffer(0);
  474. }
  475.  
  476. static void DspSpherePrim(ITEM *item)
  477. {
  478.     DrawBack(item);    
  479.     switch (SpherePrim) {
  480.       case SPH_MESH: DrawText("mesh", item); break;
  481.       case SPH_POLY: DrawText("polygon", item); break;
  482.       case SPH_LINE: DrawText("line", item); break;
  483.       case SPH_POINT: DrawText("point", item); break;
  484.     }
  485.     DrawName(item->name, &(item->rect));
  486. }
  487.  
  488. static void SelectSpherePrim(ITEM *item, long dev)
  489. {
  490.     if (dev == MIDDLEMOUSE) {
  491.     SpherePrim++;
  492.     SpherePrim %= NUMPRIMTYPES;
  493.     } else {
  494.     if (SpherePrim == 0)
  495.         SpherePrim = NUMPRIMTYPES - 1;
  496.     else SpherePrim--;
  497.     }
  498.     sphmode(SPH_PRIM, SpherePrim);
  499.     CalcInfo();
  500.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  501.     !Alreadyaccumulated)
  502.     DisplayAccScene();
  503.     else 
  504.     DisplayScene();
  505.     winset(PanelWid);
  506.     item->status = SET_PUSHED(0, item->status);
  507.     frontbuffer(1);
  508.     item->dsp(item);
  509.     frontbuffer(0);
  510. }
  511.  
  512. static void DspSphereDepth(ITEM *item)
  513. {
  514.     char str[10];
  515.  
  516.     DrawBack(item);    
  517.     sprintf(str, "%d", SphereDepth);
  518.     DrawText(str, item);
  519.     DrawName(item->name, &(item->rect));
  520. }
  521.  
  522. static void SelectSphereDepth(ITEM *item, long dev)
  523. {
  524.     if (dev == MIDDLEMOUSE) {
  525.     if (SphereDepth < SPH_MAXDEPTH) SphereDepth++;
  526.     } else if (dev == LEFTMOUSE) {
  527.     if (SphereDepth > 1) SphereDepth--;
  528.     }
  529.     sphmode(SPH_DEPTH, SphereDepth);
  530.     CalcInfo();
  531.     DisplayScene();
  532.     Alreadyaccumulated = 1;
  533.     winset(PanelWid);
  534.     item->status = SET_PUSHED(0, item->status);
  535.     frontbuffer(1);
  536.     item->dsp(item);
  537.     frontbuffer(0);
  538. }
  539.  
  540. static void SelectAtomAccBuf(ITEM *item, long dev)
  541. {
  542.     if (!hwAccbuf || BitmapSpheres)
  543.     {
  544.     winset(PanelWid);
  545.     item->status = SET_PUSHED(0, item->status);
  546.     frontbuffer(1);
  547.     item->dsp(item);
  548.     return;
  549.     }
  550.     AtomAccBuf = 1 - AtomAccBuf;
  551.     if (AtomAccBuf) 
  552.     {
  553.     InitAccBuf();
  554.     /* must force off Multisample */
  555.     if (Multisample)
  556.     {
  557.         Multisample = 0;
  558.         DoMultisample();
  559.     }
  560.     /* must force off Stereo */
  561.     if (Stereo)
  562.     {
  563.         Stereo = 0;
  564.         DoStereo();
  565.     }
  566.     }
  567.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  568.     !Alreadyaccumulated)
  569.     DisplayAccScene();
  570.     else 
  571.     DisplayScene();
  572.     winset(PanelWid);
  573.     item->status = SET_PUSHED(0, item->status);
  574.     frontbuffer(1);
  575.     item->dsp(item);
  576.     msItem->dsp(msItem);
  577.     stereoItem->dsp(stereoItem);
  578.     frontbuffer(0);
  579. }
  580.  
  581. static void SelectBondAccBuf(ITEM *item, long dev)
  582. {
  583.     if (!hwAccbuf || BitmapSpheres)
  584.     {
  585.     winset(PanelWid);
  586.     item->status = SET_PUSHED(0, item->status);
  587.     frontbuffer(1);
  588.     item->dsp(item);
  589.     return;
  590.     }
  591.     BondAccBuf = 1 - BondAccBuf;
  592.     if (BondAccBuf)
  593.     {
  594.     InitAccBuf();
  595.     /* must force off Multisample */
  596.     if (Multisample)
  597.     {
  598.         Multisample = 0;
  599.         DoMultisample();
  600.     }
  601.     /* must force off Stereo */
  602.     if (Stereo)
  603.     {
  604.         Stereo = 0;
  605.         DoStereo();
  606.     }
  607.     }
  608.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  609.     !Alreadyaccumulated)
  610.     DisplayAccScene();
  611.     else 
  612.     DisplayScene();
  613.     winset(PanelWid);
  614.     item->status = SET_PUSHED(0, item->status);
  615.     frontbuffer(1);
  616.     item->dsp(item);
  617.     msItem->dsp(msItem);
  618.     stereoItem->dsp(stereoItem);
  619.     frontbuffer(0);
  620. }
  621.  
  622. static void DspBondSmooth(ITEM *item)
  623. {
  624.     DrawBack(item);    
  625.     switch (BondSmooth) {
  626.       case SML_OFF: DrawText("Off", item); break;
  627.       case SML_ON: DrawText("On", item); break;
  628.       case SML_SMOOTHER: DrawText("Smoother", item); break;
  629.       default: break;
  630.     }
  631.     DrawName(item->name, &(item->rect));
  632. }
  633.  
  634. static void SelectBondSmooth(ITEM *item, long dev)
  635. {
  636.     static long options[] = {SML_OFF, SML_ON, SML_SMOOTHER};
  637.     static long size = 3;
  638.     static long index;
  639.     static initialized = 0;
  640.  
  641.     if (!initialized) {
  642.     int i;
  643.  
  644.     for (i = 0; i < size; i++) {
  645.         if (options[i] == BondSmooth) {
  646.         index = i;
  647.         break;
  648.         }
  649.     }
  650.     initialized = 1;
  651.     }
  652.     index++;
  653.     index %= size;
  654.     BondSmooth = options[index];
  655.     DoLineSmooth();
  656.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  657.     !Alreadyaccumulated)
  658.     DisplayAccScene();
  659.     else 
  660.     DisplayScene();
  661.     winset(PanelWid);
  662.     item->status = SET_PUSHED(0, item->status);
  663.     frontbuffer(1);
  664.     item->dsp(item);
  665.     frontbuffer(0);
  666. }
  667.  
  668. static void DspBondEndCorrect(ITEM *item)
  669. {
  670.     DrawBack(item);    
  671.     switch (BondEndCorrect) {
  672.       case SML_OFF: DrawText("Off", item); break;
  673.       case SML_END_CORRECT: DrawText("On", item); break;
  674.       default: break;
  675.     }
  676.     DrawName(item->name, &(item->rect));
  677. }
  678.  
  679. static void SelectBondEndCorrect(ITEM *item, long dev)
  680. {
  681.     static long options[] = {SML_OFF, SML_END_CORRECT};
  682.     static long index;
  683.     static initialized = 0;
  684.  
  685.     if (!initialized) {
  686.     int i;
  687.  
  688.     if (options[0] == BondSmooth) index = 0;
  689.     else index = 1;
  690.  
  691.     initialized = 1;
  692.     }
  693.     index++;
  694.     index %= 2;
  695.     BondEndCorrect = options[index];
  696.     DoLineSmooth();
  697.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  698.     !Alreadyaccumulated)
  699.     DisplayAccScene();
  700.     else DisplayScene();
  701.     winset(PanelWid);
  702.     item->status = SET_PUSHED(0, item->status);
  703.     frontbuffer(1);
  704.     item->dsp(item);
  705.     frontbuffer(0);
  706. }
  707.  
  708. static void SelectQuit(ITEM *item, long dev)
  709. {
  710.     DoExit(0);
  711. }
  712.  
  713. static void SelectHelp(ITEM *item, long dev)
  714. {
  715.     DoHelp(0);
  716.     winset(PanelWid);
  717.     frontbuffer(1);
  718.     item->dsp(item);
  719.     frontbuffer(0);
  720. }
  721.  
  722. static void SelectReset(ITEM *item, long dev)
  723. {
  724.     DoReset();
  725.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  726.     !Alreadyaccumulated)
  727.     DisplayAccScene();
  728.     else DisplayScene();
  729.     winset(PanelWid);
  730.     item->status = SET_PUSHED(0, item->status);
  731.     frontbuffer(1);
  732.     item->dsp(item);
  733.     frontbuffer(0);
  734. }
  735.  
  736. static void DspRadius(ITEM *item)
  737. {
  738.     int gap, height, width;
  739.     long vector[2];
  740.     char str[40];
  741.     long xpos_rad;
  742.  
  743.     cpack(0x0);
  744.     rectfi(item->rect.left, item->rect.bottom, item->rect.right, 
  745.     item->rect.top);
  746.     height = item->rect.top - item->rect.bottom;
  747.     gap = height / 4;
  748.     width = item->rect.right - item->rect.left - 2 * gap;
  749.     xpos_rad = item->rect.left + gap + 
  750.     (int) ((float) width * (RadScaleFactor - MinRadScaleFactor) / 
  751.     RangeRadScaleFactor);
  752.  
  753.     cpack(0xffffff);
  754.  
  755.     bgnline();
  756.     vector[0] = item->rect.left + gap;
  757.     vector[1] = item->rect.bottom + gap * 2;
  758.     v2i(vector);
  759.     vector[0] = item->rect.right - gap;
  760.     v2i(vector);
  761.     endline();
  762.  
  763.     bgnline();
  764.     vector[1] = item->rect.bottom + gap;
  765.     v2i(vector);
  766.     vector[1] = item->rect.top - gap;
  767.     v2i(vector);
  768.     endline();
  769.  
  770.     bgnline();
  771.     vector[0] = item->rect.left + gap;
  772.     v2i(vector);
  773.     vector[1] = item->rect.bottom + gap;
  774.     v2i(vector);
  775.     endline();
  776.  
  777.     bgnline();
  778.     vector[0] = xpos_rad;
  779.     v2i(vector);
  780.     vector[1] = item->rect.top - gap;
  781.     v2i(vector);
  782.     endline();
  783.  
  784.     fmsetfont(FontScreen5);
  785.  
  786.     sprintf(str, "%.2f", MinRadScaleFactor);
  787.     cmov2i(item->rect.left + 2, item->rect.bottom + 2);
  788.     fmprstr(str);
  789.  
  790.     sprintf(str, "%.2f", MaxRadScaleFactor);
  791.     cmov2i(item->rect.right - 2 - fmgetstrwidth(FontScreen5, str), 
  792.     item->rect.bottom + 2);
  793.     fmprstr(str);
  794.  
  795.     sprintf(str, "%.2f", RadScaleFactor);
  796.     cmov2i(xpos_rad - fmgetstrwidth(FontScreen5, str) / 2, 
  797.     item->rect.bottom + gap * 3 + 1);
  798.     fmprstr(str);
  799.  
  800.     DrawName(item->name, &(item->rect));
  801. }
  802.  
  803. static void SelectRadius(ITEM *item, long dev)
  804. {
  805.     int gap, height, width;
  806.     long xpos;
  807.     float fval;
  808.  
  809.     height = item->rect.top - item->rect.bottom;
  810.     gap = height / 4;
  811.     width = item->rect.right - item->rect.left - 2 * gap;
  812.     while (getbutton(LEFTMOUSE)) {
  813.     xpos = getvaluator(MOUSEX) - PanelXorigin - item->rect.left - gap;
  814.     if (xpos < 0) xpos = 0;
  815.     else if (xpos > width) xpos = width;
  816.     (*(float *)(item->val)) = (MaxRadScaleFactor - MinRadScaleFactor) * 
  817.         (float) xpos / (float) width + MinRadScaleFactor;
  818.     DrawPanel();
  819.     if (item->action)
  820.         item->action();
  821.     }
  822. }
  823.  
  824. static void DspProjection(ITEM *item)
  825. {
  826.     DrawBack(item);    
  827.     if (Perspective) DrawText("Perspective", item);
  828.     else DrawText("Ortho", item);
  829.     DrawName(item->name, &(item->rect));
  830. }
  831.  
  832. static void DspModel(ITEM *item)
  833. {
  834.     DrawBack(item);    
  835.     if (ModelId == -1) DrawText("No Model", item);
  836.     else DrawText(Models[ModelId].name, item);
  837.     DrawName(item->name, &(item->rect));
  838. }
  839.  
  840. static void SelectModel(ITEM *item, long dev)
  841. {
  842.     if (NumModels) {
  843.     if (dev == MIDDLEMOUSE) {
  844.         ModelId++;
  845.         ModelId %= NumModels;
  846.     } else {
  847.         if (ModelId <= 0) ModelId = NumModels - 1;
  848.         else ModelId--;
  849.     }
  850.     SetGeomTitle();
  851.     InitData();
  852.     CalcInfo();
  853.     if (((DispAtoms && AtomAccBuf) || (DispBonds && BondAccBuf)) &&
  854.     !Alreadyaccumulated)
  855.         DisplayAccScene();
  856.     else DisplayScene();
  857.     }
  858.     winset(PanelWid);
  859.     item->status = SET_PUSHED(0, item->status);
  860.     frontbuffer(1);
  861.     item->dsp(item);
  862.     frontbuffer(0);
  863. }
  864.  
  865. static void SelectMultisample(ITEM *item, long dev)
  866. {
  867.     if (!hwMultisample || BitmapSpheres)
  868.     {
  869.     winset(PanelWid);
  870.     item->status = SET_PUSHED(0, item->status);
  871.     frontbuffer(1);
  872.     item->dsp(item);
  873.     return;
  874.     }
  875.     Multisample = 1 - Multisample;
  876.     if (Multisample)
  877.     { /* Must turn off acc buff */
  878.     AtomAccBuf = 0;
  879.     BondAccBuf = 0;
  880.     /* must force off Stereo */
  881.     if (Stereo)
  882.     {
  883.         Stereo = 0;
  884.         DoStereo();
  885.     }
  886.     }
  887.     if (item->action)
  888.     item->action();
  889.     DisplayScene();
  890.     winset(PanelWid);
  891.     item->status = SET_PUSHED(0, item->status);
  892.     frontbuffer(1);
  893.     item->dsp(item);
  894.     accAtomItem->dsp(accAtomItem);
  895.     accBondItem->dsp(accBondItem);
  896.     stereoItem->dsp(stereoItem);
  897.     frontbuffer(0);
  898. }
  899.  
  900. static void SelectStereo(ITEM *item, long dev)
  901. {
  902.     if (!hwStereo)
  903.     {
  904.     winset(PanelWid);
  905.     item->status = SET_PUSHED(0, item->status);
  906.     frontbuffer(1);
  907.     item->dsp(item);
  908.     return;
  909.     }
  910.     Stereo = 1 - Stereo;
  911.     if (Stereo)
  912.     {
  913.     { /* Must turn off acc buff */
  914.         AtomAccBuf = 0;
  915.         BondAccBuf = 0;
  916.     }
  917.     /* force off Multisample - may not have enough memory */
  918.     if (Multisample)
  919.     {
  920.         Multisample = 0;
  921.         DoMultisample();
  922.     }
  923.     }
  924.     if (item->action)
  925.     item->action();
  926.     DisplayScene();
  927.     winset(PanelWid);
  928.     item->status = SET_PUSHED(0, item->status);
  929.     frontbuffer(1);
  930.     item->dsp(item);
  931.     accAtomItem->dsp(accAtomItem);
  932.     accBondItem->dsp(accBondItem);
  933.     msItem->dsp(msItem);
  934.     frontbuffer(0);
  935. }
  936.  
  937. static void SelectPerspective(ITEM *item, long dev)
  938. {
  939.     SelectOnOff(item, dev);
  940. }
  941.  
  942. static void SelectBitmapSpheres(ITEM *item, long dev)
  943. {
  944.     if (!hwBitmapSpheres)
  945.     {
  946.     winset(PanelWid);
  947.     item->status = SET_PUSHED(0, item->status);
  948.     frontbuffer(1);
  949.     item->dsp(item);
  950.     return;
  951.     }
  952.     BitmapSpheres = 1 - BitmapSpheres;
  953.     if (BitmapSpheres)
  954.     {
  955.     { /* Must turn off acc buff */
  956.         AtomAccBuf = 0;
  957.         BondAccBuf = 0;
  958.     }
  959.     /* force off Multisample - may not have enough memory */
  960.     if (Multisample)
  961.     {
  962.         Multisample = 0;
  963.         DoMultisample();
  964.     }
  965.     }
  966.     if (item->action)
  967.     item->action();
  968.     DisplayScene();
  969.     winset(PanelWid);
  970.     item->status = SET_PUSHED(0, item->status);
  971.     frontbuffer(1);
  972.     item->dsp(item);
  973.     accAtomItem->dsp(accAtomItem);
  974.     accBondItem->dsp(accBondItem);
  975.     msItem->dsp(msItem);
  976.     projItem->dsp(projItem);
  977.     frontbuffer(0);
  978. }
  979.  
  980.